import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:cv/cv_json.dart';
import 'package:fijkplayer/fijkplayer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pure/database.dart';
import 'package:pure/model.dart';
import 'package:pure/request.dart';

typedef VodList = List<Vod>;

Future importSource() async {
  final s = await rootBundle.loadString("assets/source.json");
  final srs = jsonDecode(s);
  final list = srs['source'] as List;
  for (var element in list) {
    final VodSource vs = VodSource();
    vs.base.v = element['base'];
    vs.name.v = element['name'];
    vs.sync.v = 0;
    vs.vodCount.v = 0;
    vs.vodTotal.v = 0;
    await DataBaseUtil.saveVodSource(vs);
  }
  DataBaseUtil.prefs!.setBool(DataBaseUtil.firstRun, false);
  log('import source complete');
}

final ValueNotifier<int> config = ValueNotifier(0);

List<VodSource> globalSourceList = [];

void main() async {
  runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();
    await DataBaseUtil.init();
    final first = DataBaseUtil.prefs!.getBool(DataBaseUtil.firstRun);
    if (first == null || first) {
      await importSource();
    }
    globalSourceList = await DataBaseUtil.listVodSource();
    final current = DataBaseUtil.prefs!.getInt(DataBaseUtil.currentSource);
    if (current == null) {
      config.value = 0;
    } else {
      config.value = current;
    }
    cvAddBuilder<Vod>((_) => Vod());
    cvAddBuilder<VodSource>((_) => VodSource());
    runApp(const MyApp());
  }, (error, stack) {
    log(error.toString());
  });
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '纯纯播放器',
      theme: ThemeData(
        useMaterial3: false,
        colorSchemeSeed:const Color(0xff282828)
      ),
      debugShowCheckedModeBanner: false,
      home: const Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}


class VodHome extends StatefulWidget {
  const VodHome({super.key});

  @override
  State<VodHome> createState() => _VodHomeState();
}

class _VodHomeState extends State<VodHome> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}


class _HomeState extends State<Home> {
  int pg = 1;
  VodList list = [];
  String err = '';

  _reload() {
    setState(() {
      pg = 1;
      list.clear();
    });
    _load();
  }

  @override
  void initState() {
    _load();
    config.addListener(_reload);
    super.initState();
  }

  _load() {
    try {
      String base = globalSourceList[config.value].base.v ?? '';
      if (base.isEmpty) {
        return;
      }
      HRequest.getVodList(base, page: pg).then((value) {
        list.addAll(value.list.v ?? []);
        pg += 1;
        if (mounted) {
          setState(() {});
        }
      });
    } catch (_) {
      setState(() {
        err = '当前资源不可用';
        list.clear();
        pg = 1;
      });
    }
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
        appBar: AppBar(
          title: const Text('纯纯播放器'),
          titleTextStyle: const TextStyle(color: Colors.white, fontSize: 18),
          backgroundColor: const Color(0xff282828),
          actions: [
            IconButton(
                onPressed: () async {},
                icon: const Icon(
                  Icons.search,
                  color: Colors.white,
                )),
            IconButton(
                onPressed: () {
                  Navigator.push(
                      context,
                      CupertinoPageRoute(
                          builder: (context) => const SourceList()));
                },
                icon: const Icon(
                  Icons.list,
                  color: Colors.white,
                ))
          ],
        ),
        backgroundColor: const Color(0xff444444),
        body: err.isNotEmpty
            ? Center(
                child: Text(
                  err,
                  style: const TextStyle(color: Colors.grey, fontSize: 18),
                ),
              )
            : list.isEmpty
                ? const Center(
                    child: Text('加载中...'),
                  )
                : RefreshIndicator(
                    onRefresh: () async {
                      _reload();
                    },
                    child: Padding(
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      child: CustomScrollView(
                        slivers: [
                          SliverPadding(
                              padding: const EdgeInsets.symmetric(vertical: 8.0),
                              sliver: SliverList.separated(
                                itemBuilder: (context, index) {
                                  final v = list[index];

                                  Widget r = InkWell(
                                    onTap: () {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  Play(vod: v)));
                                    },
                                    child: Container(
                                      color: const Color(0xff282828),
                                      child: Column(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.stretch,
                                        children: [
                                          SizedBox(
                                            child: Image.network(
                                              v.pic.v ?? '',
                                              fit: BoxFit.cover,
                                              height: 140,
                                              errorBuilder: (
                                                BuildContext context,
                                                Object error,
                                                StackTrace? stackTrace,
                                              ) {
                                                return const Icon(
                                                    Icons.broken_image);
                                              },
                                            ),
                                          ),
                                          Container(
                                            padding: const EdgeInsets.symmetric(
                                                horizontal: 4),
                                            decoration: const BoxDecoration(
                                                color: Color(0xff282828)),
                                            child: DefaultTextStyle(
                                              style: TextStyle(
                                                color: Color(0xff888888)
                                              ),
                                              child: Column(
                                                mainAxisSize: MainAxisSize.min,
                                                crossAxisAlignment:
                                                    CrossAxisAlignment.start,
                                                children: [
                                                  Text(
                                                    v.name.v ?? ''
                                                  ),
                                                  Text(
                                                    '${v.area.v}/${v.clss.v}/${v.typeName.v}/${v.year.v}',
                                                    style: const TextStyle(
                                                        fontSize: 10,
                                                        ),
                                                  ),
                                                  Text('${v.time.v} 更新',
                                                      style: const TextStyle(
                                                          fontSize: 10,
                                                          ))
                                                ],
                                              ),
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                  );
                                  if (index == list.length - 1) {
                                    _load();
                                    r = Column(
                                      children: [
                                        r,
                                        const Padding(
                                          padding: EdgeInsets.all(8.0),
                                          child: CircularProgressIndicator(),
                                        )
                                      ],
                                    );
                                  }
                                  return r;
                                },
                                separatorBuilder: (context, index) {
                                  return const SizedBox(
                                    height: 8,
                                  );
                                },
                                itemCount: list.length,
                              ))
                        ],
                      ),
                    ),
                  ));
  }
}

class Play extends StatefulWidget {
  const Play({super.key, required this.vod});

  final Vod vod;

  @override
  State<Play> createState() => _PlayState();
}

class _PlayState extends State<Play> {
  final FijkPlayer player = FijkPlayer();

  List<Map<String, String>> ps = [];

  String err = '';
  int current = 0;

  @override
  void initState() {
    super.initState();
    widget.vod.playUrl.v?.split("#").forEach((element) {
      ps.add({'p': element.split("\$").first, 'u': element.split("\$").last});
    });
    if (ps.isNotEmpty) {
      final url = ps.first['u'] ?? '';
      if (url.isNotEmpty) {
        player.setDataSource(url, autoPlay: true, showCover: true);
      } else {
        setState(() {
          err = '解析失败！';
        });
      }
    } else {
      setState(() {
        err = '解析失败！';
      });
    }
  }

  @override
  void dispose() {
    player.release();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          '${widget.vod.name.v}',
          style: const TextStyle(color: Colors.white),
        ),
        backgroundColor: const Color(
          0xff282828,
        ),
        centerTitle: true,
        foregroundColor: Colors.white,
        actions: [
          IconButton(onPressed: () {}, icon: const Icon(Icons.download))
        ],
      ),
      backgroundColor: const Color(0xff444444),
      body: Column(
        children: [
          Container(
              constraints: BoxConstraints(
                maxHeight: MediaQuery.of(context).size.height * .35,
              ),
              child: Center(
                  child: FijkView(
                player: player,
                fit: FijkFit.cover,
                fsFit: FijkFit.cover,
                color: Colors.deepPurple,
              ))),
          Expanded(
            child: SingleChildScrollView(
              child: DefaultTextStyle(
                style: const TextStyle(color: Color(0xffdddddd)),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      padding: const EdgeInsets.all(8),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                              '${widget.vod.name.v}/${widget.vod.area.v}/${widget.vod.clss.v}/${widget.vod.typeName.v}/${widget.vod.year.v}'),
                          Text('演员：${widget.vod.actor.v}'),
                          Text('导演：${widget.vod.director.v}'),
                          Text('剧情简介：${widget.vod.blurb.v}'),
                        ],
                      ),
                    ),
                    Container(
                      padding: const EdgeInsets.all(8),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Padding(
                            padding: EdgeInsets.only(bottom: 8.0),
                            child: Text('分集'),
                          ),
                          Wrap(
                              spacing: 8,
                              runSpacing: 8,
                              children: List.generate(ps.length, (index) {
                                final p = ps[index];
                                return InkWell(
                                  child: Container(
                                    padding: const EdgeInsets.symmetric(
                                        vertical: 4, horizontal: 12),
                                    decoration: BoxDecoration(
                                        color: current == index
                                            ? Colors.deepPurple
                                            : const Color(0xff666666),
                                        borderRadius: BorderRadius.circular(4)),
                                    child: Text(
                                      '${p['p']}',
                                      style: TextStyle(
                                          color: current == index
                                              ? Colors.white
                                              : const Color(0xff282828)),
                                    ),
                                  ),
                                  onTap: () async {
                                    await player.reset();
                                    current = index;
                                    final url = p['u'] ?? '';
                                    if (url.isEmpty) {
                                      err = '解析失败';
                                    } else {
                                      player.setDataSource(url, autoPlay: true);
                                    }
                                    setState(() {});
                                  },
                                );
                              }))
                        ],
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class SourceList extends StatefulWidget {
  const SourceList({super.key});

  @override
  State<SourceList> createState() => _SourceListState();
}

class _SourceListState extends State<SourceList> {
  List<VodSource> sources = [];

  _load() {
    DataBaseUtil.listVodSource().then((value) {
      globalSourceList = value;
      if (mounted) {
        setState(() {
          sources = value;
        });
      }
    });
  }

  @override
  void initState() {
    _load();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          '资源列表',
          style: TextStyle(color: Colors.white),
        ),
        foregroundColor: Colors.white,
        centerTitle: true,
        backgroundColor: const Color(0xff282828),
        actions: [
          IconButton(
              onPressed: () {
                Navigator.push(
                        context,
                        CupertinoPageRoute(
                            builder: (context) => const VodSourceEdit()))
                    .then((value) => _load());
              },
              icon: const Icon(Icons.add))
        ],
      ),
      backgroundColor: const Color(0xff444444),
      body: ValueListenableBuilder(
        valueListenable: config,
        builder: (BuildContext context, int value, Widget? child) {
          return ListView.separated(
            itemBuilder: (context, index) {
              final r = sources[index];
              return InkWell(
                onTap: () {
                  Navigator.push(
                      context,
                      CupertinoPageRoute(
                          builder: (context) => VodSourceEdit(
                                vodSource: r,
                                index: index,
                              ))).then((value) => _load());
                },
                child: Container(
                  padding: const EdgeInsets.all(8.0),
                  decoration: const BoxDecoration(color: Color(0xff282828)),
                  child: DefaultTextStyle(
                    style: const TextStyle(color: Color(0xff666666)),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('${r.name.v}'),
                        Text('${r.base.v}'),
                        Text('${r.id.v}'),
                        Text(
                          config.value == index ? '當前使用' : '',
                          style: const TextStyle(
                              color: Colors.blueAccent,
                              fontWeight: FontWeight.bold),
                        )
                      ],
                    ),
                  ),
                ),
              );
            },
            itemCount: sources.length,
            separatorBuilder: (context, index) {
              return const SizedBox(
                height: 8,
              );
            },
          );
        },
      ),
    );
  }
}

class VodSourceEdit extends StatefulWidget {
  const VodSourceEdit({super.key, this.vodSource, this.index});

  final VodSource? vodSource;
  final int? index;

  @override
  State<VodSourceEdit> createState() => _VodSourceEditState();
}

class _VodSourceEditState extends State<VodSourceEdit> {
  final TextEditingController _nameCtl = TextEditingController();
  final TextEditingController _baseCtl = TextEditingController();

  @override
  void initState() {
    if (widget.vodSource != null) {
      _nameCtl.text = widget.vodSource!.name.v ?? '';
      _baseCtl.text = widget.vodSource!.base.v ?? '';
    }
    super.initState();
  }

  @override
  void dispose() {
    _nameCtl.dispose();
    _baseCtl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('编辑资源'),
        centerTitle: true,
        actions: [
          IconButton(
              onPressed: () async {
                if (_nameCtl.text.isEmpty) {
                  return;
                }
                if (_baseCtl.text.isEmpty) {
                  return;
                }
                if (widget.vodSource != null) {
                  widget.vodSource!.name.v = _nameCtl.text;
                  widget.vodSource!.base.v = _baseCtl.text;
                  await DataBaseUtil.saveVodSource(widget.vodSource!);
                } else {
                  final vs = VodSource();
                  vs.base.v = _baseCtl.text;
                  vs.name.v = _nameCtl.text;
                  await DataBaseUtil.saveVodSource(vs);
                }
                if (context.mounted) {
                  Navigator.pop(context);
                }
              },
              icon: const Icon(Icons.check))
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('名称'),
                TextFormField(
                  controller: _nameCtl,
                  decoration: const InputDecoration(
                    isDense: true,
                    border: InputBorder.none,
                    filled: true,
                  ),
                ),
              ],
            ),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('地址'),
                TextFormField(
                  controller: _baseCtl,
                  maxLines: null,
                  decoration: const InputDecoration(
                    isDense: true,
                    border: InputBorder.none,
                    filled: true,
                  ),
                ),
              ],
            ),
            if (widget.index != null)
              ValueListenableBuilder(
                valueListenable: config,
                builder: (BuildContext context, value, Widget? child) {
                  return SwitchListTile(
                    contentPadding: EdgeInsets.zero,
                    value: config.value == widget.index,
                    onChanged: (value) {
                      if (value) {
                        config.value = widget.index!;
                      } else {
                        config.value = 0;
                      }
                      DataBaseUtil.prefs!
                          .setInt(DataBaseUtil.currentSource, config.value);
                    },
                    title: const Text('设为默认'),
                  );
                },
              ),
            if (widget.vodSource != null)
              InkWell(
                onTap: () async {
                  if (widget.index == config.value) {
                    showDialog(
                        context: context,
                        builder: (context) {
                          return const AlertDialog(
                            title: Text('正在使用當前資源'),
                            content: Text('取消默認再刪除'),
                          );
                        });
                    return;
                  }
                  await DataBaseUtil.delVodSource(widget.vodSource!.id.v ?? '');
                  if (context.mounted) {
                    Navigator.pop(context);
                  }
                },
                child: FractionallySizedBox(
                  widthFactor: .65,
                  child: Container(
                    decoration: BoxDecoration(
                        color: Colors.red,
                        borderRadius: BorderRadius.circular(4)),
                    padding: const EdgeInsets.symmetric(vertical: 8),
                    child: const Center(
                      child: Text(
                        '删除',
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  ),
                ),
              )
          ],
        ),
      ),
    );
  }
}
